home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Belgian Amiga Club - ADF Collection
/
BS1 part 34.zip
/
BS1 part 34
/
FredFish PD 317.adf
/
Uniq
/
uniq.c
< prev
Wrap
C/C++ Source or Header
|
1990-02-06
|
8KB
|
472 lines
/************************************************************************
* *
* *
* Filename: uniq.c *
* *
* uniq - compact repeated lines Author: John Woods *
* *
* ( looks like UNIX version ) *
* *
* Written 02/08/86 by John Woods, placed into public domain. Enjoy. *
* *
* Amiga port by Gary Duncan , Canberra Australia *
* *
* *
*-----------------------------------------------------------------------*
*
*
*
* Modification record:
*~~~~~~~~~~~~~~~~~~~~
*
* Date By whom Change
* ---- ------- ------
*
* JW Original
* 04Jan90 GMD Amiga port : reformatted, headers
* added , usage() added.
* +/-n option bug fixed
*
* Function Description
* ~~~~~~~~ ~~~~~~~~~~~
*+ main
*+ skip
*+ equal
*+ show
*+ uniq
*+ usage
*+ getline
*+ xfopen
*+
*
*
*******************************************************************************/
#include "stdio.h"
#include "ctype.h"
/*
* give a version # ( GMD )
*/
#define VERS "1.1"
/* If the symbol WRITE_ERROR is defined, uniq will exit(1) if it gets a
* write error on the output. This is not (of course) how V7 uniq does it,
* so undefine the symbol if you want to lose your output to a full disk
*/
#define WRITE_ERROR 1
#define GBUF 1024
extern char *MakeDate[] ;
FILE *fopen();
FILE *xfopen();
char xbuffer [BUFSIZ];
int xuflag = 1; /* default is union of -d and -u outputs */
int xdflag = 1; /* flags are mutually exclusive */
int xcflag = 0;
int xfields = 0;
int xchars = 0;
char *xcurline ;
char *xprevline ;
char xbuf1 [GBUF] ;
char xbuf2 [GBUF] ;
/***************************************************************************
Name : main
Purpose: ..every C prog deserves one..
Entry :
Returns :
****************************************************************************/
int
main(argc,argv)
char *argv[];
{
char *p;
int inf = -1, outf;
if (argc == 1 )
{
usage() ;
exit (1) ;
}
setbuf(stdout, xbuffer);
for (--argc, ++argv; (argc > 0) && (**argv == '-' || **argv == '+');
--argc, ++argv)
{
if (**argv == '+')
xchars = atoi(*argv + 1);
else if (isdigit(argv[0][1]))
xfields = atoi(*argv + 1);
else if (argv[0][1] == '\0')
inf = 0; /* - is stdin */
else
{
for (p = *argv+1; *p; p++) {
switch(*p) {
case 'd':
xdflag = 1;
xuflag = 0;
break;
case 'u':
xuflag = 1;
xdflag = 0;
break;
case 'c':
xcflag = 1;
break;
default:
usage();
exit(1) ;
}
}
}
}
/* input file */
if (argc == 0)
inf = 0;
else
if (inf == -1) { /* if - was not given */
fclose(stdin);
xfopen(*argv++, "r");
argc--;
}
if (argc == 0)
outf = 1;
else {
fclose(stdout);
xfopen(*argv++, "w");
argc--;
}
uniq();
fflush(stdout);
exit(0);
}
/***************************************************************************
Name : skip
Purpose:
+- n options ; skip fields / charas in fields
Entry :
Returns :
ptr to (+nth) chara in (-nth)field
or NULL if not found
****************************************************************************/
char *skip(s)
char *s;
{
int n;
/* skip xfields */
for (n = xfields; n > 0 ; --n)
{
/* skip blanks */
while (*s && (*s == ' ' || *s == '\t'))
s++;
if (!*s)
return s;
while (*s && (*s != ' ' && *s != '\t'))
s++;
if (!*s)
return s;
}
/* skip characters */
for (n = xchars; n > 0; --n) {
if (!*s)
return s;
s++;
}
return s;
}
/***************************************************************************
Name : equal
Purpose:
tests 2 strings for equality
Entry :
Returns :
****************************************************************************/
int equal(s1, s2)
char *s1, *s2;
{
return !strcmp( skip(s1), skip(s2));
}
/***************************************************************************
Name : show
Purpose:
Entry :
Returns :
****************************************************************************/
void
show(line,count)
int count ;
char *line;
{
if (xcflag)
printf("%4d %s", count,line);
else {
if ((xuflag && count == 1) || (xdflag && count != 1))
printf("%s", line);
}
}
/***************************************************************************
Name : uniq
Purpose:
Entry :
Returns :
****************************************************************************/
int
uniq()
{
char *ptr;
int seen = 1 ;
/* initialise "prev" line ( setup ?? ) */
xprevline = xbuf1;
if (getline(xprevline, GBUF) < 0)
return(0);
xcurline = xbuf2;
/* get xcurline and compare
* if not equal, dump xprevline and swap pointers
* else continue, bumping seen count
*/
while (getline(xcurline, GBUF) > 0) {
if (!equal(xprevline, xcurline)) {
show(xprevline, seen);
seen = 1;
ptr = xcurline;
xcurline = xprevline;
xprevline = ptr;
}
else
seen += 1;
}
show(xprevline, seen);
return 0;
}
/***************************************************************************
Name : getline
Purpose:
Entry :
Returns :
-1 ; EOF
# of charas read
****************************************************************************/
int getline(buf,count)
char *buf;
int count;
{
char c;
char * cats = buf ;
int ct = 0;
while (ct++ < count)
{
c = getc(stdin);
if (c <= 0)
return(-1);
*cats++ = c;
if (c == '\n')
{
*cats++ = 0;
/*
* read another line if no 'n' compliance
*/
if ( xchars || xfields )
{
if ( *skip(buf) == '\0' )
{
ct = 0 ;
cats = buf ;
}
else /* exit */
return (ct) ;
}
else
return (ct) ;
}
}
return(ct);
}
/***************************************************************************
Name : xfopen
Purpose:
Entry :
Returns :
v****************************************************************************/
FILE *xfopen(fn, mode)
char *fn, *mode;
{
FILE *p;
extern int errno;
extern char *sys_errlist[];
if ((p = fopen(fn,mode)) == NULL) {
perror("uniq");
fflush(stdout);
exit(1);
}
return (p);
}
/***************************************************************************
Name : usage
Purpose:
Entry :
Returns :
****************************************************************************/
int
usage()
{
static char *rats[] = {
" - Written by John Woods (Amiga port by Gary Duncan)\n",
"usage: uniq [-udc] [+n] [-n] [input [output]]" ,
" -c ; print lines , count repeated ones",
" -d ; print first occurrence of replicated lines only (default)",
" -u ; print only unique lines",
" +n ; skip n charas from start of field",
" -n ; skip n fields from start of line",
""
} ;
int j = 0 ;
char * ptr ;
fprintf(stderr, "uniq: Version %s [ %s ]\n" , VERS , MakeDate[0] ) ;
while ( *(ptr=rats[j++]) )
fprintf(stderr,"%s\n" , ptr );
}